﻿// ----------------------------------------------------------------------
// <author name="Moses Kehengu"/>
// <copyright file="IQService.asmx.cs" company="Futures Group International">
//     Copyright statement. All right reserved
// </copyright>
//
// ------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using System.Data;
using System.Configuration;
using GenericTools;
using System.IO;
using System.Threading;
using System.Data.Common;
using GenericTools.Models;
using DataModels.Common;
using DataModels.Enumerations;
using GenericTools.OptionBPlus;
using System.Linq;
using System.Reflection;
using System.Web.Services.Protocols;
using GenericTools.CustomReporting;


namespace IQWebServices
{
    /// <summary>
    /// Summary description for Service1
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [System.ComponentModel.ToolboxItem(false)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    // [System.Web.Script.Services.ScriptService]
    public class IQService : System.Web.Services.WebService
    {
        private const string AUTHENTICATION_FAILED = "Authentication Failed";
        private readonly string OPERATION_IS_DEPRECATED = String.Format("This operation can not be performed in this version. Please update your IQSMS.{0}You can download the latest version in this address: {0}{1}",
            Environment.NewLine, Properties.Settings.Default.DownloadAddress);

        public AuthenticationHeader Authentication;

        static IQService()
        {
            string connectionName = "IQSMS_TestDBContext";
            AppConfiguration.DBConnectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
            AppConfiguration.DBProviderName = ConfigurationManager.ConnectionStrings[connectionName].ProviderName;
            
            AppConfiguration.ApplicationName = Properties.Settings.Default.ApplicationName;
            AppConfiguration.EnableErrorLogMail = Properties.Settings.Default.EnableErrorLogMail;
            AppConfiguration.ErrorLogEmailAddress = Properties.Settings.Default.ErrorLogEmailAddress;
            AppConfiguration.LogFileDirectory = Properties.Settings.Default.LogFileDirectory;
            
            AppConfiguration.MailFrom = Properties.Settings.Default.MailFrom;
            AppConfiguration.MailPassword = Properties.Settings.Default.MailPassword;
            AppConfiguration.MailServer = Properties.Settings.Default.MailServer;
            AppConfiguration.MailServerPort = Properties.Settings.Default.MailServerPort;
            AppConfiguration.MailUsername = Properties.Settings.Default.MailUsername;
            
            AppConfiguration.MaximumErrorTolerance = Properties.Settings.Default.MaxErrorCount;
            AppConfiguration.MaximumReportDelay = Properties.Settings.Default.MaximumReportDelay;

            AppConfiguration.OfflineDataCacheLifetime = Properties.Settings.Default.OfflineDataCacheLifetime;
            AppConfiguration.AccessMethod = DataAccessMethod.DIRECT_ACCESS;
            AppConfiguration.DHISBaseUrl = Properties.Settings.Default.DHISBaseUrl;
            //AppConfiguration.DataCached = Properties.Settings.Default.DataCached;
            //AppConfiguration.WebServiceURL = Properties.Settings.Default.WeServiceURL;

            //connectionName = "IQWebServices.Properties.Settings.CacheDBConnection";
            //AppConfiguration.CacheDBProviderName = ConfigurationManager.ConnectionStrings[connectionName].ProviderName;
            //AppConfiguration.CacheDBConnectionString = ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;

            //AppConfiguration.SSISPackageFilename = Properties.Settings.Default.SSISPackageFilename;
            //AppConfiguration.SourceConnectionStringForPackage = Properties.Settings.Default.SourceConnectionStringForPackage;
            //AppConfiguration.DestinationConnectionStringForPackage = Properties.Settings.Default.DestinationConnectionStringForPackage;
        }

        #region Regions,Districts and Facilities
        [WebMethod]
        public string GetID(string name, ReportLevel reportLevel)
        {
            string output = Utilities.GetID(name, reportLevel);
            output = DataTransformation.Encrypt(output);
            return output;
        }

        [WebMethod]
        public string GetAllRegions()
        {
            DataTable dataTable = Utilities.GetAllRegions();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllRegionsBySupportingPartner(int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetAllRegions(supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllDistricts()
        {
            DataTable dataTable = Utilities.GetAllDistricts();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllDistrictsBySupportingPartner(int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetAllDistricts(supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllFacilities()
        {
            DataTable dataTable = Utilities.GetAllFacilities();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrict(int districtID)
        {
            DataTable dataTable = Utilities.GetDistrict(districtID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegion(int regionID)
        {
            DataTable dataTable = Utilities.GetRegion(regionID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityDistrict(string facilityCode)
        {
            DataTable dataTable = Utilities.GetFacilityDistrict(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityRegion(string facilityCode)
        {
            DataTable dataTable = Utilities.GetFacilityRegion(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictRegion(int districtID)
        {
            DataTable dataTable = Utilities.GetDistrictRegion(districtID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionName(int regionID)
        {
            string name = Utilities.GetRegionName(regionID);
            string output = DataTransformation.Encrypt(name);
            return output;
        }

        [WebMethod]
        public string GetRegionNameFromDistrict(int districtID)
        {
            string name = Utilities.GetRegionNameFromDistrict(districtID);
            string output = DataTransformation.Encrypt(name);
            return output;
        }

        [WebMethod]
        public string GetDistrictName(int districtID)
        {
            string name = Utilities.GetDistrictName(districtID);
            string output = DataTransformation.Encrypt(name);
            return output;
        }

        [WebMethod]
        public string GetFacilityDetails(string facilityCode)
        {
            DataTable dataTable = Utilities.GetFacilityDetails(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityExpectedReports(string facilityCode)
        {
            DataTable dataTable = Utilities.GetFacilityExpectedReports(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityTypes()
        {
            DataTable dataTable = Utilities.GetFacilityTypes();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region User Management
        [WebMethod]
        public string ChangePassword(int userID, string oldPassword, string newPassword)
        {
            bool status = Utilities.ChangePassword(userID, oldPassword, newPassword);
            string output = DataTransformation.Encrypt(status.ToString());
            return output;
        }

        [WebMethod]
        public string GetUserInformationByUsername(string username)
        {
            DataTable dataTable = Utilities.GetUserInformation(username);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetUserInformationByUsernamePassword(string username, string password)
        {
            DataTable dataTable = Utilities.GetUserInformation(username, password);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetUserInformationByID(int userID)
        {
            DataTable dataTable = Utilities.GetUserInformation(userID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region FacilityDetails Class Methods
        [WebMethod]
        [Obsolete("This method does not provide enough information. Use FacilityDetailsInsert3")]
        public string FacilityDetailsInsert(string code, string name, string shortname, int region, int district,
            string description, string address, string principalContact, int status, string remarks,
            DateTime PMTCTStartDateTime, DateTime LDStartDateTime, DateTime prophylaxisDateTime,
            DateTime ANCStartDateTime, DateTime HEIDStartDate, bool provideANC, bool provideHEID, bool providePMTCT,
            bool provideLD, bool provideProphylaxis, DateTime activeDateTime, DateTime inactiveDateTime, bool trained)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;

            //bool okToContinue = Utilities.FacilityDetailsInsert(code, name, shortname, region, district, description,
            //    address, principalContact, status, remarks, PMTCTStartDateTime, LDStartDateTime, prophylaxisDateTime,
            //    ANCStartDateTime, HEIDStartDate, provideANC, provideHEID, providePMTCT, provideLD, provideProphylaxis,
            //    activeDateTime, inactiveDateTime, trained);

            //string output = DataTransformation.Encrypt(okToContinue.ToString());
            //return output;
        }

        [WebMethod]
        [Obsolete("This method is here for backward compatibility, Use FacilityDetailsInsert3 instead")]
        public string FacilityDetailsInsert2(string code, string name, string internalName, string shortname, int region, int district,
            string description, string address, string principalContact, string remarks,
            DateTime LDStartDateTime, DateTime prophylaxisDateTime, DateTime ANCStartDateTime, DateTime HEIDStartDate, 
            bool provideANC, bool provideHEID, bool provideLD, bool provideProphylaxis, DateTime activityDateTime, 
            bool actived, bool trained, bool provideDBS, int facilityType, string userSignature)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;

            //bool authenticated = Utilities.AuthenticateUser(userSignature);
            //if (authenticated)
            //{
            //    string id = DataTransformation.Decrypt(userSignature);
            //    int userId = Int32.Parse(id);

            //    bool okToContinue = Utilities.FacilityDetailsInsert2(code, name, internalName, shortname, region, 
            //        district, description, address, principalContact, remarks, LDStartDateTime, 
            //        prophylaxisDateTime, ANCStartDateTime, HEIDStartDate, provideANC, provideHEID, 
            //        provideLD, provideProphylaxis, activityDateTime, actived, trained, provideDBS, facilityType, userId);

            //    string output = DataTransformation.Encrypt(okToContinue.ToString());
            //    return output;
            //}
            //else
            //{
            //    throw new Exception("You are not authenticated to perform this operation");
            //}            
        }

        [WebMethod]
        public string FacilityDetailsInsert3(string code, string name, string internalName, string shortname, int region, int district,
            string description, string address, string principalContact, string remarks,
            DateTime LDStartDateTime, DateTime prophylaxisDateTime, DateTime ANCStartDateTime, DateTime HEIDStartDate,
            bool provideANC, bool provideHEID, bool provideLD, bool provideProphylaxis, DateTime activityDateTime,
            bool actived, bool trained, bool provideDBS, int facilityType, int supportingPartnerId, string userSignature, int status)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                string id = DataTransformation.Decrypt(userSignature);
                int userId = Int32.Parse(id);

                bool okToContinue = Utilities.FacilityDetailsInsert2(code, name, internalName, shortname, region,
                    district, description, address, principalContact, remarks, LDStartDateTime,
                    prophylaxisDateTime, ANCStartDateTime, HEIDStartDate, provideANC, provideHEID,
                    provideLD, provideProphylaxis, activityDateTime, actived, trained, provideDBS, 
                    facilityType, supportingPartnerId, userId, status);

                string output = DataTransformation.Encrypt(okToContinue.ToString());
                return output;
            }
            else
            {
                throw new Exception("You are not authenticated to perform this operation");
            }
        }

        [Obsolete("This method is here for backward compatibility, Use FacilityDetailsUpdate3 instead")]
        [WebMethod]
        public string FacilityDetailsUpdate(string oldCode, string code, string name, string shortname, int region, int district,
            string description, string address, string principalContact, int status, string remarks,
            DateTime PMTCTStartDateTime, DateTime LDStartDateTime, DateTime prophylaxisDateTime,
            DateTime ANCStartDateTime, DateTime HEIDStartDate, bool provideANC, bool provideHEID, bool providePMTCT,
            bool provideLD, bool provideProphylaxis, DateTime activeDateTime, DateTime inactiveDateTime, bool trained)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;

            //bool okToContinue = Utilities.FacilityDetailsUpdate(oldCode, code, name, shortname, region, district, description,
            //    address, principalContact, status, remarks, PMTCTStartDateTime, LDStartDateTime, prophylaxisDateTime,
            //    ANCStartDateTime, HEIDStartDate, provideANC, provideHEID, providePMTCT, provideLD, provideProphylaxis,
            //    activeDateTime, inactiveDateTime, trained);

            //string output = DataTransformation.Encrypt(okToContinue.ToString());
            //return output;
        }

        [Obsolete("This method is here for backward compatibility, Use FacilityDetailsUpdate3 instead")]
        [WebMethod]
        public string FacilityDetailsUpdate2(string oldCode, string code, string name, string internalName, string shortname, 
            int region, int district, string description, string address, string principalContact, string remarks,
            DateTime LDStartDateTime, DateTime prophylaxisDateTime, DateTime ANCStartDateTime, DateTime HEIDStartDate, 
            bool provideANC, bool provideHEID, bool provideLD, bool provideProphylaxis, DateTime activityDateTime, 
            bool actived, bool trained, bool provideDBS, int facilityType, string userSignature)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;

            //bool authenticated = Utilities.AuthenticateUser(userSignature);
            //if (authenticated)
            //{
            //    string id = DataTransformation.Decrypt(userSignature);
            //    int userId = Int32.Parse(id);

            //    bool okToContinue = Utilities.FacilityDetailsUpdate2(oldCode, code, name, internalName, shortname, region, 
            //        district, description, address, principalContact, remarks, LDStartDateTime, prophylaxisDateTime,
            //        ANCStartDateTime, HEIDStartDate, provideANC, provideHEID, provideLD, provideProphylaxis,
            //        activityDateTime, actived, trained, provideDBS, facilityType, userId);

            //    string output = DataTransformation.Encrypt(okToContinue.ToString());
            //    return output;
            //}
            //else
            //{
            //    throw new Exception("You are not authenticated to perform this operation");
            //}    
        }

        [WebMethod]
        public string FacilityDetailsUpdate3(string oldCode, string code, string name, string internalName, string shortname,
            int region, int district, string description, string address, string principalContact, string remarks,
            DateTime LDStartDateTime, DateTime prophylaxisDateTime, DateTime ANCStartDateTime, DateTime HEIDStartDate,
            bool provideANC, bool provideHEID, bool provideLD, bool provideProphylaxis, DateTime activityDateTime,
            bool actived, bool trained, bool provideDBS, int facilityType, int supportingPartnerId, string userSignature)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                string id = DataTransformation.Decrypt(userSignature);
                int userId = Int32.Parse(id);

                bool okToContinue = Utilities.FacilityDetailsUpdate2(oldCode, code, name, internalName, shortname, region,
                    district, description, address, principalContact, remarks, LDStartDateTime, prophylaxisDateTime,
                    ANCStartDateTime, HEIDStartDate, provideANC, provideHEID, provideLD, provideProphylaxis,
                    activityDateTime, actived, trained, provideDBS, facilityType, supportingPartnerId, userId);

                string output = DataTransformation.Encrypt(okToContinue.ToString());
                return output;
            }
            else
            {
                throw new Exception("You are not authenticated to perform this operation");
            }
        }

        [WebMethod]
        public void FacilityDetailsSaveExpectedReports2(string code, List<int> iExpectedReports, 
            List<DateTime> dExpectedReports, List<bool> bExpectedReports)
        {
            if ((iExpectedReports.Count != dExpectedReports.Count) || 
                (iExpectedReports.Count != bExpectedReports.Count))
            {
                throw new Exception("List counts does not match");
            }

            DataTable expectedReports = new DataTable();
            DataColumn column = new DataColumn("ReportId", Type.GetType("System.Int32"));
            expectedReports.Columns.Add(column);
            column = new DataColumn("ReportingStartDate", Type.GetType("System.DateTime"));
            expectedReports.Columns.Add(column);
            column = new DataColumn("DirectEntry", Type.GetType("System.Boolean"));
            expectedReports.Columns.Add(column);
            
            //Dictionary<int, DateTime> expectedReports = new Dictionary<int, DateTime>();
            for (int i = 0; i < iExpectedReports.Count; i++)
            {
                int reportId = iExpectedReports[i];
                DateTime reportingStartDate = dExpectedReports[i];
                bool directEntry = bExpectedReports[i];
                
                DataRow r = expectedReports.NewRow();
                r["ReportId"] = reportId;
                r["ReportingStartDate"] = reportingStartDate;
                r["DirectEntry"] = directEntry;
                expectedReports.Rows.Add(r);
                //expectedReports[key] = value;
            }           

            Utilities.FacilityDetailsSaveExpectedReports(code, expectedReports);
        }

        [WebMethod]
        [Obsolete("This method does not provide enough information. Use FacilityDetailsSaveExpectedReports2")]
        public void FacilityDetailsSaveExpectedReports(string code, List<int> expectedReports)
        {
            //Utilities.FacilityDetailsSaveExpectedReports(code, expectedReports);
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;
        }

        [WebMethod]
        public string FacilityDetailsCanDeleteFacility(string code)
        {
            bool status = Utilities.FacilityDetailsCanDeleteFacility(code);
            string output = DataTransformation.Encrypt(status.ToString());
            return output;
        }

        [WebMethod]
        public string FacilityDetailsDelete(string facilityCode)
        {
            bool status = Utilities.FacilityDetailsDelete(facilityCode);
            string output = DataTransformation.Encrypt(status.ToString());
            return output;
        }
        #endregion

        #region Reports Methods
        [WebMethod]
        public string GetAllExpectedReports()
        {
            DataTable dataTable = Utilities.GetAllExpectedReports();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllExpectedReportViews()
        {
            DataTable dataTable = Utilities.GetAllExpectedReportViews();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllReportYears()
        {
            DataTable dataTable = Utilities.GetAllReportYears();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllReportPeriods()
        {
            DataTable dataTable = Utilities.GetAllReportPeriods();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        #region Missing Reports
        [WebMethod]
        public string GetMissingFacilityReport(string facilityCode, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetMissingFacilityReport(facilityCode, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetMissingDistrictReport(int districtID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetMissingDistrictReport(districtID, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetMissingRegionReport(int regionID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetMissingRegionReport(regionID, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetMissingNationReport(int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetMissingNationReport(report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetMissingDistrictReportBySupportingPartner(int districtID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetMissingDistrictReport(districtID, report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetMissingRegionReportBySupportingPartner(int regionID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetMissingRegionReport(regionID, report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetMissingNationReportBySupportingPartner(int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetMissingNationReport(report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region Submitted Reports
        [WebMethod]
        public string GetSubmittedFacilityReport(string facilityCode, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetSumittedFacilityReport(facilityCode, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSubmittedDistrictReport(int districtID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetSubmittedDistrictReport(districtID, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSubmittedDistrictReportBySupportingPartner(int districtID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetSubmittedDistrictReport(districtID, report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSubmittedRegionReport(int regionID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetSubmittedRegionReport(regionID, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSubmittedRegionReportBySupportingPartner(int regionID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetSubmittedRegionReport(regionID, report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSubmittedNationReport(int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetSubmittedNationReport(report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSubmittedNationReportBySupportingPartner(int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetSubmittedNationReport(report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion      

        #region Report Counting
        [WebMethod]
        public string GetFacilityReportCount(string facilityCode, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetFacilityReportCount(facilityCode, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictReportCount(int districtID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetDistrictReportCount(districtID, report,
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictReportCountBySupportingPartner(int districtID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetDistrictReportCount(districtID, report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionReportCount(int regionID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetRegionReportCount(regionID, report, 
                startYear, startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionReportCountBySupportingPartner(int regionID, int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetRegionReportCount(regionID, report,
                startYear, startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetNationReportCount(int report, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetNationReportCount(report, startYear, 
                startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetNationReportCountBySupportingPartner(int report, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetNationReportCount(report, startYear,
                startPeriod, endYear, endPeriod, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region Report Data
        [WebMethod]
        public string GetDistrictReport(int districtID, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetDistrictReport(districtID, reportID, startYear,
                startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictReportBySupportingPartner(int districtID, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingPartner, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetDistrictReport(districtID, reportID, startYear,
                startPeriod, endYear, endPeriod, supportingPartner, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictReport2(int districtID, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetDistrictReport(districtID, reportID, startYear,
                startPeriod, endYear, endPeriod, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionReport(int regionID, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetRegionReport(regionID, reportID, startYear,
                startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionReportBySupportingPartner(int regionID, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod, int supportingParterId, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetRegionReport(regionID, reportID, startYear,
                startPeriod, endYear, endPeriod, supportingParterId, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionReport2(int regionID, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetRegionReport(regionID, reportID, startYear,
                startPeriod, endYear, endPeriod, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetNationReport(int reportID, int startYear, int startPeriod,
            int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetNationReport(reportID, startYear,
                startPeriod, endYear, endPeriod);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetNationReport2(int reportID, int startYear, int startPeriod,
            int endYear, int endPeriod, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetNationReport(reportID, startYear, 
                startPeriod, endYear, endPeriod, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetBulkEachFacilityReport(int reportId, DateTime startDate, DateTime endDate)
        {
            DataTable dataTable = Utilities.GetBulkEachFacilityReport(reportId, startDate, endDate);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetNationReportBySupportingPartner(int reportID, int startYear, int startPeriod,
            int endYear, int endPeriod, int supportingPartnerId, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetNationReport(reportID, startYear,
                startPeriod, endYear, endPeriod, supportingPartnerId, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityReport(string facilityCode, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod)
        {
            DataTable dataTable = Utilities.GetFacilityReport(facilityCode, reportID, startYear,
                startPeriod, endYear, endPeriod, false);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityReport2(string facilityCode, int reportID, int startYear,
            int startPeriod, int endYear, int endPeriod, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetFacilityReport(facilityCode, reportID, startYear,
                startPeriod, endYear, endPeriod, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        [WebMethod]
        public string GetReportSubmissionInfo(int reportID, int year, int period, string facilityCode)
        {
            DataTable dataTable = Utilities.GetReportSubmissionInfo(reportID, year, period, facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllExpectedCharts()
        {
            DataTable dataTable = Utilities.GetAllExpectedCharts();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetChartIndicators(int chartID)
        {
            DataTable dataTable = Utilities.GetChartIndicators(chartID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        #region Donor Report
        [WebMethod]
        public string DonorReportGetReportDataTable(ReportLevel level, object levelID, DonorReportParts part,
            DateTime startingDateTime, DateTime endingDateTime)
        {
            DataTable dataTable = Utilities.GetReportDataTable(level, levelID, part, startingDateTime, endingDateTime);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region Charts
        [WebMethod]
        public string GetChartData(ReportLevel level, object levelID, int startYear, int startPeriod,
            int endYear, int endPeriod, List<ChartIndicatorInfo> reportIndicators)
        {
            DataTable dataTable = Utilities.GetChartData(level, levelID, startYear, startPeriod,
                endYear, endPeriod, reportIndicators);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion
        #endregion

        #region Facility Management Methods
        [WebMethod]
        public string GetAllFacilitiesStatus()
        {
            DataTable datable = Utilities.GetAllFacilitiesStatus();
            string output = DataTransformation.Serialize(datable);
            return output;
        }

        [WebMethod]
        public string GetAllFacilitiesStatusBySupportingPartner(int supportingPartnerId)
        {
            DataTable datable = Utilities.GetAllFacilitiesStatus(supportingPartnerId);
            string output = DataTransformation.Serialize(datable);
            return output;
        }

        [WebMethod]
        public string GetAllRegionFacilitiesStatus(int regionID)
        {
            DataTable dataTable = Utilities.GetAllRegionFacilitiesStatus(regionID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllRegionFacilitiesStatusBySupportingPartner(int regionID, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetAllRegionFacilitiesStatus(regionID, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllDistrictFacilitiesStatus(int districtID)
        {
            DataTable dataTable = Utilities.GetAllDistrictFacilitiesStatus(districtID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityStatus(string facilityCode)
        {
            DataTable dataTable = Utilities.GetFacilityStatus(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetOtherSystemsFacilityDetails(int systemId, string internalFacilityCode, string userSignature)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                string plainText = DataTransformation.Decrypt(userSignature);
                int iActionUserId = Int32.Parse(plainText);
                DataTable dataTable = Utilities.GetOtherSystemsFacilityDetails(systemId, internalFacilityCode, iActionUserId);
                string output = DataTransformation.Serialize(dataTable);
                return output;
            }
            else
            {
                return AUTHENTICATION_FAILED;
            }             
        }

        [WebMethod]
        public string SaveOtherSystemDetails(int systemId, string internalFacilityCode, string facilityCode,
            string facilityName, string districtName, string regionName, string userSignature)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                string plainText = DataTransformation.Decrypt(userSignature);
                int iActionUserId = Int32.Parse(plainText);
                bool okToContinue = OtherSystem.SaveOtherSystemDetails(systemId, internalFacilityCode,
                    facilityCode, facilityName, districtName, regionName, iActionUserId);
                string output = DataTransformation.Encrypt(okToContinue.ToString());
                return output;
            }
            else
            {
                return AUTHENTICATION_FAILED;
            }             
        }

        [WebMethod]
        public string GetOtherSystem(int systemId)
        {
            DataTable dataTable = Utilities.GetOtherSystem(systemId);
            string output = DataTransformation.Serialize(dataTable);
            return output;           
        }

        [WebMethod]
        public string GetOtherSystems()
        {
            DataTable dataTable = Utilities.GetOtherSystems();
            string output = DataTransformation.Serialize(dataTable);
            return output;      
        }

        [WebMethod]
        public string GetDistrictsByRegion(int regionID)
        {
            DataTable dataTable = Utilities.GetDistrictsByRegion(regionID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictsByRegionBySupportingPartner(int regionID, int supportingPartner)
        {
            DataTable dataTable = Utilities.GetDistrictsByRegion(regionID, supportingPartner);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region SMS Reminder Methods
        #region By Facility
        [WebMethod]
        public string GetFacilitiesWithoutReport(int reportID, int period, int year)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(reportID, period, year);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutReportFilteredByDistrict(int reportID, int period, int year, int filteringDistrict)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(reportID, period, year, filteringDistrict, null);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutReportFilteredByRegion(int reportID, int period, int year, int filteringRegion)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(reportID, period, year, null, filteringRegion);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutAtLeastOneReport(int period, int year)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(period, year);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutAtLeastOneReportFilteredByDistrict(int period, int year, int filteringDistrict)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(period, year, filteringDistrict, null);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutAtLeastOneReportFilteredByRegion(int period, int year, int filteringRegion)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(period, year,null, filteringRegion);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutReportBySupportingPartner(int reportID, int period, 
            int year, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(reportID, period, 
                year, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutReportFilteredByDistrictBySupportingPartner(int reportID, int period,
            int year, int supportingPartnerId, int filteringDistrict)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(reportID, period, year,
                supportingPartnerId, filteringDistrict);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutReportFilteredByRegionBySupportingPartner(int reportID, int period,
            int year, int supportingPartnerId, int filteringRegion)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(reportID, period, year,
                supportingPartnerId, filteringRegion, default(bool));
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutAtLeastOneReportBySupportingPartner(int period,
            int year, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(period,
                year, supportingPartnerId, default(bool));
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutAtLeastOneReportFilteredByDistrictBySupportingPartner(int period,
            int year, int supportingPartnerId, int filteredDistrict)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(period,
                year, supportingPartnerId, filteredDistrict, default(bool));
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesWithoutAtLeastOneReportFilteredByRegionBySupportingPartner(int period,
            int year, int supportingPartnerId, int filteredRegion)
        {
            DataTable dataTable = Utilities.GetFacilitiesWithoutReport(period,
                year, supportingPartnerId, default(bool), filteredRegion);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region By District
        [WebMethod]
        public string GetDistrictFacilitiesWithoutReport(int districtID, int reportID, int period, int year)
        {
            DataTable dataTable = Utilities.GetDistrictFacilitiesWithoutReport(districtID, 
                reportID, period, year);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictFacilitiesWithoutAtLeastOneReport(int districtID, int period, int year)
        {
            DataTable dataTable = Utilities.GetDistrictFacilitiesWithoutReport(districtID, period, year);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region By Region
        [WebMethod]
        public string GetRegionFacilitiesWithoutReport(int regionID, int reportID, int period, int year)
        {
            DataTable dataTable = Utilities.GetRegionFacilitiesWithoutReport(regionID, reportID, period, year);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionFacilitiesWithoutAtLeastOneReport(int regionID, int period, int year)
        {
            DataTable dataTable = Utilities.GetRegionFacilitiesWithoutReport(regionID, period, year);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionFacilitiesWithoutReportBySupportingPartner(int regionID, int reportID, 
            int period, int year, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetRegionFacilitiesWithoutReport(regionID, reportID, 
                period, year, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionFacilitiesWithoutReportFilteredByDistrictBySupportingPartner(int regionID, 
            int reportID, int period, int year, int supportingPartnerId, int filteringDistrict)
        {
            DataTable dataTable = Utilities.GetRegionFacilitiesWithoutReport(regionID, reportID,
                period, year, supportingPartnerId, filteringDistrict);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionFacilitiesWithoutAtLeastOneReportBySupportingPartner(int regionID,
            int period, int year, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetRegionFacilitiesWithoutReport(regionID,
                period, year, supportingPartnerId, default(bool));
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionFacilitiesWithoutAtLeastOneReportFilteredByDistrictBySupportingPartner(
            int regionID, int period, int year, int supportingPartnerId, int filteringDistrict)
        {
            DataTable dataTable = Utilities.GetRegionFacilitiesWithoutReport(regionID,
                period, year, supportingPartnerId, filteringDistrict, default(bool));
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        [WebMethod]
        public string GetRegisteredReportingUsers(string facilityCode)
        {
            DataTable dataTable = Utilities.GetRegisteredReportingUsers(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public void SendSMSReminderWithPhoneNumbers(int reportID, int year, int period, string message,
            List<List<string>> facilitiesPhoneNumbers, List<string> facilitiesCodes, bool repeat)
        {
            Utilities.SendSMSReminderWithPhoneNumbers(reportID, year, period, message, facilitiesPhoneNumbers, facilitiesCodes, repeat);
        }

        [WebMethod]
        public void SendSMSReminder(int reportID, int year, int period, string message,
            List<string> numbersToExclude, List<string> facilitiesCodes, bool repeat)
        {
            Utilities.SendSMSReminder(reportID, year, period, message, numbersToExclude, facilitiesCodes, repeat);
        }

        [WebMethod]
        public string GetReportingStatus(string facilityCode, int period, int year)
        {
            DataTable dataTable = Utilities.GetReportingStatus(facilityCode, period, year);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public void SaveReminderReceiver(string facilityCode, List<string> numbers)
        {
            Utilities.SaveReminderReceiver(facilityCode, numbers);
        }
        #endregion

        #region Translation
        [WebMethod]
        public string GetAllLanguage()
        {
            DataTable dataTable = Utilities.GetAllLanguages();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllTranslationByLanguage(int languageID)
        {
            DataTable dataTable = Utilities.GetAllTranslationByLanguage(languageID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetTranslationByLabelNo(int languageID, int labelNo)
        {
            DataTable dataTable = Utilities.GetTranslationByLabelNo(languageID, labelNo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string UpdateTranslation(int transID, string languageText)
        {
            bool status = Utilities.UpdateTranslation(transID, languageText);
            string output = DataTransformation.Encrypt(status.ToString());
            return output;
        }

        [WebMethod]
        public string GetTranslationText(string cellnum, int labelID)
        {
            string output = Utilities.GetTranslationText(cellnum, labelID);
            output = DataTransformation.Encrypt(output);
            return output;
        }
        #endregion

        #region Assistance Management
        [WebMethod]
        public string GetRegisteredUsers()
        {
            DataTable dataTable = Utilities.GetRegisteredUsers();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegisteredUserContacts(int userID)
        {
            DataTable dataTable = Utilities.GetRegisteredUserContacts(userID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string UpdateRegisteredUserContacts(int userID, string cellnum, string email)
        {
            bool status = Utilities.SaveRegisteredUserContacts(userID, cellnum, email);
            string output = DataTransformation.Encrypt(status.ToString());
            return output;
        }

        [WebMethod]
        public void AssignToUser(ReportLevel level, int userID, List<string> assignmentIDs)
        {
            Utilities.AssignToUser(level, userID, assignmentIDs);
        }

        [WebMethod]
        public string AssistanceGetAssignedRegions(int userToExclude)
        {
            DataTable dataTable = Utilities.GetAssignedRegions(userToExclude);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSelectedUserAssignedRegions(int userID)
        {
            DataTable dataTable = Utilities.GetSelectedUserAssignedRegions(userID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetAssignedAllRegions()
        {
            DataTable dataTable = Utilities.GetAssignedRegions();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetSelectedUserAssignedDistricts(int userID)
        {
            DataTable dataTable = Utilities.GetSelectedUserAssignedDistricts(userID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetAssignedAllDistricts()
        {
            DataTable dataTable = Utilities.GetAssignedDistricts();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetAssignedAllDistrictsBySupportingPartner(int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetAssignedDistricts(supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetAssignedDistricts(int userToExclude)
        {
            DataTable dataTable = Utilities.GetAssignedDistricts(userToExclude);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetAssignedAllFacilities()
        {
            DataTable dataTable = Utilities.GetAssignedFacilities();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetSelectedUserAssignedFacilities(int userID)
        {
            DataTable dataTable = Utilities.GetSelectedUserAssignedFacilities(userID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string AssistanceGetAssignedFacilities(int userToExclude)
        {
            DataTable dataTable = Utilities.GetAssignedFacilities(userToExclude);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilityAssignedUsers(string facilityCode)
        {
            DataTable dataTable = Utilities.GetFacilityAssignedUsers(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetRegionAssignedUsers(int regionID)
        {
            DataTable dataTable = Utilities.GetRegionAssignedUsers(regionID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDistrictAssignedUsers(int districtID)
        {
            DataTable dataTable = Utilities.GetDistrictAssignedUsers(districtID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region Blocked Reports
        [WebMethod]
        public string GetBlockedReports()
        {
            DataTable dataTable = Utilities.GetBlockedReports();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetBlockedReportsBySupportingPartner(int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetBlockedReports(supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetBlockedReportsByDistrict(int districtId)
        {
            DataTable dataTable = Utilities.GetBlockedReportsByDistrict(districtId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetBlockedReportsByDistrictBySupportingPartner(int districtId, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetBlockedReportsByDistrict(districtId, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetBlockedReportsByRegion(int regionId)
        {
            DataTable dataTable = Utilities.GetBlockedReportsByRegion(regionId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetBlockedReportsByRegionBySupportingPartner(int regionId, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetBlockedReportsByRegion(regionId, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public void DeleteBlockedReport(int reportID, string FacCode, int period, int year)
        {
            Utilities.DeleteBlockedReport(reportID, FacCode, period, year);
        }

        [WebMethod]
        public void DeleteBlockedUserReport(string senderNumber)
        {
            Utilities.DeleteBlockedUserReport(senderNumber);
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public void ClearAllBlockedNumbers()
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            // Only administrator can perform this kind of operation
            if (userProfile.AccessLevel.AccessName.Equals(DataModels.Models.AccessLevel.ADMINISTRATOR_LEVEL,
                    StringComparison.InvariantCultureIgnoreCase))
            {
                throw new Exception("You do not have enough privilege to perform this operation");
            }

            Utilities.ClearAllBlockedNumbers();
        }
        #endregion

        #region Data Capture
        [WebMethod]
        public string GetAllFacilitiesDetails(bool basicInfo)
        {
            DataTable dataTable = Utilities.GetAllFacilitiesDetails(false, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllFacilitiesDetailsBySupportingPartner(int supportingPartnerId, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetAllFacilitiesDetails(supportingPartnerId, false, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllFacilitiesDetails_Alpha()
        {
            DataTable dataTable = Utilities.GetAllFacilitiesDetails_Alpha();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllFacilitiesDetailsByKnownSystem(int systemId)
        {
            DataTable dataTable = Utilities.GetAllFacilitiesDetailsByKnownSystem(systemId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public List<DataModels.ModelViews.OtherSystemsFacilityDetailView> GetKnownSystemsFacilityDetails(int systemId)
        {
            var results = Utilities.GetOtherSystemsFacilityDetails(systemId);
            return results;
        }

        [WebMethod]
        public DataModels.ModelViews.OtherSystemsFacilityDetailView GetKnownSystemsFacilityDetail(int systemId, string internalFacilityCode)
        {
            var results = Utilities.GetOtherSystemsFacilityDetails(systemId, internalFacilityCode);
            return results;
        }

        [WebMethod]
        public List<DataModels.Models.OtherSystemsDistrictDetail> GetKnownSystemsDistrictDetails(int systemId)
        {
            var results = Utilities.GetOtherSystemsDistrictDetails(systemId);
            return results;
        }

        [WebMethod]
        public DataModels.Models.OtherSystemsDistrictDetail GetKnownSystemsDistrictDetail(int systemId, int internalDistrictId)
        {
            var results = Utilities.GetOtherSystemsDistrictDetails(systemId, internalDistrictId);
            return results;
        }

        [WebMethod]
        public List<DataModels.Models.OtherSystemsRegionDetail> GetKnownSystemsRegionDetails(int systemId)
        {
            var results = Utilities.GetOtherSystemsRegionDetails(systemId);
            return results;
        }

        [WebMethod]
        public DataModels.Models.OtherSystemsRegionDetail GetKnownSystemsRegionDetail(int systemId, int internalRegionId)
        {
            var results = Utilities.GetOtherSystemsRegionDetails(systemId, internalRegionId);
            return results;
        }


        [WebMethod]
        public string GetAllFacilitiesDetails_AlphaBySupportingPartner(int supportintPartnerId)
        {
            DataTable dataTable = Utilities.GetAllFacilitiesDetails_Alpha(supportintPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesDetailsByDistrict2(int districtID, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetFacilitiesDetailsByDistrict(districtID, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesDetailsByDistrictBySupportingPartner(int districtID, int supportingPartnerId, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetFacilitiesDetailsByDistrict(districtID, supportingPartnerId, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [Obsolete("For simple list of facilities use GetAllFacilitiesDetailsbyDistrict2 instead")]
        [WebMethod]
        public string GetFacilitiesDetailsByDistrict(int districtID)
        {
            DataTable dataTable = Utilities.GetFacilitiesDetailsByDistrict(districtID, false);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        
        [WebMethod]
        public string GetFacilitiesDetailsByRegion2(int regionID, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetFacilitiesDetailsByRegion(regionID, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetFacilitiesDetailsByRegionBySupportingPartner(int regionID, int supportingPartnerId, bool basicInfo)
        {
            DataTable dataTable = Utilities.GetFacilitiesDetailsByRegion(regionID, supportingPartnerId, basicInfo);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [Obsolete("For simple list of facilities use GetAllFacilitiesDetailsbyRegion2 instead")]
        [WebMethod]
        public string GetFacilitiesDetailsByRegion(int regionID)
        {
            DataTable dataTable = Utilities.GetFacilitiesDetailsByRegion(regionID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetReportAllDataDescriptions(int reportID)
        {
            DataTable dataTable = Utilities.GetReportAllDataDescriptions(reportID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetReportDetails(int reportID)
        {
            DataTable dataTable = Utilities.GetReportDetails(reportID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        [Obsolete("Use SendReportWithComments which supports report comments")]
        public string SendReport(string senderNum, string reportingText/*, string userSignature*/)
        {
            bool authenticated = true;// Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                ReportingMessage reportingMessage = Utilities.SendReport(senderNum, reportingText, false);//, userSignature);
                DataTable dataTable = new DataTable("ReportingMessage");
                DataColumn column = new DataColumn("Status", Type.GetType("System.Int32"));
                dataTable.Columns.Add(column);
                column = new DataColumn("Message", Type.GetType("System.String"));
                dataTable.Columns.Add(column);

                DataRow row = dataTable.NewRow();
                row["Message"] = reportingMessage.Message;
                row["Status"] = reportingMessage.Status;
                dataTable.Rows.Add(row);

                string output = DataTransformation.Serialize(dataTable);
                return output;
            }
            else return AUTHENTICATION_FAILED;
        }

        [WebMethod]
        public string SendReportWithComments(string senderNum, string reportingText/*, string userSignature*/, string comments)
        {
            bool authenticated = true;// Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                ReportingMessage reportingMessage = Utilities.SendReport(senderNum, reportingText, false, comments);//, userSignature);
                DataTable dataTable = new DataTable("ReportingMessage");
                DataColumn column = new DataColumn("Status", Type.GetType("System.Int32"));
                dataTable.Columns.Add(column);
                column = new DataColumn("Message", Type.GetType("System.String"));
                dataTable.Columns.Add(column);

                DataRow row = dataTable.NewRow();
                row["Message"] = reportingMessage.Message;
                row["Status"] = reportingMessage.Status;
                dataTable.Rows.Add(row);

                string output = DataTransformation.Serialize(dataTable);
                return output;
            }
            else return AUTHENTICATION_FAILED;
        }

        [WebMethod]
        public string SendReport2(string senderNum, string reportingText/*, string userSignature*/, bool allowingSameMonthReporting)
        {
            bool authenticated = true;// Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                ReportingMessage reportingMessage = Utilities.SendReport(senderNum, reportingText, allowingSameMonthReporting);//, userSignature);
                DataTable dataTable = new DataTable("ReportingMessage");
                DataColumn column = new DataColumn("Status", Type.GetType("System.Int32"));
                dataTable.Columns.Add(column);
                column = new DataColumn("Message", Type.GetType("System.String"));
                dataTable.Columns.Add(column);

                DataRow row = dataTable.NewRow();
                row["Message"] = reportingMessage.Message;
                row["Status"] = reportingMessage.Status;
                dataTable.Rows.Add(row);

                string output = DataTransformation.Serialize(dataTable);
                return output;
            }
            else return AUTHENTICATION_FAILED;
        }

        [WebMethod]
        public string SendMergingReport(string senderNum, string reportingText)
        {
            bool authenticated = true;// Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                SMSReportingFormat SMSFormat = SMSReportingFormat.RESTRICTIVE;
                DataInputingMethod inputMethod = DataInputingMethod.DESKTOP_DATA_MERGING;
                ReportingMessage reportingMessage = Merging.SendReport(senderNum, reportingText, SMSFormat, inputMethod);//, userSignature);
                DataTable dataTable = new DataTable("ReportingMessage");
                DataColumn column = new DataColumn("Status", Type.GetType("System.Int32"));
                dataTable.Columns.Add(column);
                column = new DataColumn("Message", Type.GetType("System.String"));
                dataTable.Columns.Add(column);

                DataRow row = dataTable.NewRow();
                row["Message"] = reportingMessage.Message;
                row["Status"] = reportingMessage.Status;
                dataTable.Rows.Add(row);

                string output = DataTransformation.Serialize(dataTable);
                return output;
            }
            else return AUTHENTICATION_FAILED;
        }
        #endregion

        #region Report Management
        [WebMethod]
        public string CreateReport(string name, string repVersion, int dataCount, string description, 
            string comments, bool usedAsView, string userSignature)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                string id = DataTransformation.Decrypt(userSignature);
                int userId = Int32.Parse(id);
                bool status = Utilities.CreateReport(name, repVersion, dataCount, description, 
                    comments, usedAsView, userId);
                string output = DataTransformation.Encrypt(status.ToString());
                return output;
            }
            else
            {
                throw new Exception("You are not authenticated to perform this operation");
            }
        }

        [WebMethod]
        public string IsRepVersionUsable(string repVersion)
        {
            bool status = Utilities.IsRepVersionUsable(repVersion);
            string output = DataTransformation.Encrypt(status.ToString());
            return output;
        }

        [WebMethod]
        public string ReportCanBeDeleted(int reportID)
        {
            bool status = Utilities.ReportCanBeDeleted(reportID);
            string output = DataTransformation.Encrypt(status.ToString());
            return output;
        }

        [WebMethod]
        public void DeleteReport(int reportID)
        {
            Utilities.DeleteReport(reportID);
        }

        [WebMethod]
        public string GetReportDataLocations(int reportID)
        {
            DataTable dataTable = Utilities.GetReportDataLocations(reportID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetReportDataLocationsCount(int reportID)
        {
            int count = Utilities.GetReportDataLocationsCount(reportID);
            string output = DataTransformation.Encrypt(count.ToString());
            return output;
        }

        [WebMethod]
        public void SetReportDataLocations(int reportID, string[][] data)
        {
            Utilities.SetReportDataLocations(reportID, data);
        }

        [WebMethod]
        public string UpdateReportKeyword(int reportID, string keyword)
        {
            bool updated = Utilities.UpdateReportKeyword(reportID, keyword);
            string output = DataTransformation.Encrypt(updated.ToString());
            return output;
        }
        #endregion

        #region Report Rules Management
        [WebMethod]
        public string GetReportRules(int reportID)
        {
            DataTable dataTable = Utilities.GetReportRules(reportID);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllReportRulesComparison()
        {
            DataTable dataTable = Utilities.GetAllComparison();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string DeleteReportRule(int reportID, int ruleID)
        {
            bool deleted = Utilities.DeleteReportRule(reportID, ruleID);
            string output = DataTransformation.Encrypt(deleted.ToString());
            return output;
        }

        [WebMethod]
        public string InsertReportRule(int reportID, int measurePosNo, string ruleDescription,
            string comparedToOrderPos, int comparisonType, bool multicomparison)
        {
            bool inserted = Utilities.InsertReportRule(reportID, measurePosNo, ruleDescription,
                comparedToOrderPos, comparisonType, multicomparison);
            string output = DataTransformation.Encrypt(inserted.ToString());
            return output;
        }

        [WebMethod]
        public string UpdateReportRule(int reportID, int measurePosNo, string ruleDescription,
            string comparedToOrderPos, int comparisonType, bool multicomparison, int BRNo)
        {
            bool updated = Utilities.UpdateReportRule(reportID, measurePosNo, ruleDescription,
                comparedToOrderPos, comparisonType, multicomparison, BRNo);
            string output = DataTransformation.Encrypt(updated.ToString());
            return output;
        }
        #endregion

        #region Repoort Merging
        [WebMethod]
        public string GetAllReportMerge()
        {
            DataTable dataTable = Merging.GetAllReportMerge();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetDestinationMergingReport(int mergeId)
        {
            DataTable dataTable = Merging.GetDestinationMergingReport(mergeId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSourceMergingReport(int mergeId)
        {
            DataTable dataTable = Merging.GetSourceMergingReports(mergeId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetReportDataMerging(int mergeId)
        {
            DataTable dataTable = Merging.GetReportDataMerging(mergeId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public MergingOperationStatus MergeFacilityReports(int mergeId, bool overwrite, string facilityCode, int startYear,
            int startMonth, int endYear, int endMonth, string senderNum)
        {
            var status = Merging.MergeFacilityReports(mergeId, overwrite, facilityCode, startYear, startMonth, endYear, endMonth, senderNum);
            return status;
        }

        [WebMethod]
        public MergingOperationStatus MergeDistrictReports(int mergeId, bool overwrite, int districtId, int startYear,
            int startMonth, int endYear, int endMonth, string senderNum)
        {
            var status = Merging.MergeDistrictReports(mergeId, overwrite, districtId, startYear, startMonth, endYear, endMonth, senderNum);
            return status;
        }

        [WebMethod]
        public MergingOperationStatus MergeRegionReports(int mergeId, bool overwrite, int regionId, int startYear,
            int startMonth, int endYear, int endMonth, string senderNum)
        {
            var status = Merging.MergeRegionReports(mergeId, overwrite, regionId, startYear, startMonth, endYear, endMonth, senderNum);
            return status;
        }

        [WebMethod]
        public MergingOperationStatus MergeNationReports(int mergeId, bool overwrite, int startYear,
            int startMonth, int endYear, int endMonth, string senderNum)
        {
            var status = Merging.MergeNationReports(mergeId, overwrite, startYear, startMonth, endYear, endMonth, senderNum);
            return status;
        }

        #endregion

        #region User Management
        [Obsolete("This method is here for backward compatibility, use UpdateUserDetails2 instead")]
        [WebMethod]
        public string UpdateUserDetails(int id, string firstname, string lastname,
            string password, string email, string phoneNumber, AccessLevel level, string levelValue)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;
            //bool success = Utilities.UpdateUserDetails(id, firstname, lastname, password, email, phoneNumber, level, levelValue);
            //string output = DataTransformation.Encrypt(success.ToString());
            //return output;
        }

        [WebMethod]
        public string UpdateUserDetails2(int id, string firstname, string lastname, string password, 
            string email, string phoneNumber, AccessLevel level, string levelValue, 
            int supportingPartnerId, string userSignature)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                string plainText = DataTransformation.Decrypt(userSignature);
                int iActionUserId = Int32.Parse(plainText);
                bool success = Utilities.UpdateUserDetails(id, firstname, lastname, password, email, phoneNumber,
                    level, levelValue, supportingPartnerId, iActionUserId);
                string output = DataTransformation.Encrypt(success.ToString());
                return output;
            }
            else
            {
                return AUTHENTICATION_FAILED;
            }
        }

        [WebMethod]
        public string GetAllUsers()
        {
            DataTable dataTable = Utilities.GetAllUsers();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllUsersBySupportingPartner(int supportingPartner)
        {
            DataTable dataTable = Utilities.GetAllUsers(supportingPartner);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetUsersByFacility(string facilityCode)
        {
            DataTable dataTable = Utilities.GetUsersByFacility(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetUsersByDistrict(int district)
        {
            DataTable dataTable = Utilities.GetUsersByDistrict(district);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetUsersByRegion(int region)
        {
            DataTable dataTable = Utilities.GetUsersByRegion(region);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllSMSUsers()
        {
            DataTable dataTable = Utilities.GetAllSMSUsers();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllSMSUsersBySupportingPartner(int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetAllSMSUsers(supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllSMSUsersByRegion(int regionId)
        {
            DataTable dataTable = Utilities.GetAllSMSUsersByRegion(regionId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllSMSUsersByRegionBySupportingPartner(int regionId, int supportingPartnerId)
        {
            DataTable dataTable = Utilities.GetAllSMSUsersByRegion(regionId, supportingPartnerId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllSMSUsersByDistrict(int districtId)
        {
            DataTable dataTable = Utilities.GetAllSMSUsersByDistrict(districtId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAllSMSUsersByFacility(string facilityCode)
        {
            DataTable dataTable = Utilities.GetAllSMSUsersByFacility(facilityCode);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string DeleteSMSUser(int id, string actionUserId)
        {
            bool authenticated = Utilities.AuthenticateUser(actionUserId);
            if (authenticated)
            {
                string plainText = DataTransformation.Decrypt(actionUserId);
                int iActionUserId = Int32.Parse(plainText);
                bool success = Utilities.DeleteSMSUser(id, iActionUserId);
                string output = DataTransformation.Encrypt(success.ToString());
                return output;
            }
            else
            {
                return AUTHENTICATION_FAILED;
            }
        }

        [Obsolete("This is method is there for backward compatibility, use AddSMSUser2 instead")]
        [WebMethod]
        public string AddSMSUser(string phoneNumber, string fullname, int language, string facilityCode, 
            string email, string actionUserId)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;
            //bool authenticated = Utilities.AuthenticateUser(actionUserId);
            //if (authenticated)
            //{
            //    string plainText = DataTransformation.Decrypt(actionUserId);
            //    int iActionUserId = Int32.Parse(plainText);
            //    bool success = Utilities.AddSMSUser(phoneNumber, fullname, language, facilityCode, email, iActionUserId);
            //    string output = DataTransformation.Encrypt(success.ToString());
            //    return output;
            //}
            //else
            //{
            //    return AUTHENTICATION_FAILED;
            //}
        }

        [WebMethod]
        public string AddSMSUser2(string phoneNumber, string fullname, int language, string facilityCode, 
            string email, int title, string actionUserId)
        {
            bool authenticated = Utilities.AuthenticateUser(actionUserId);
            if (authenticated)
            {
                string plainText = DataTransformation.Decrypt(actionUserId);
                int iActionUserId = Int32.Parse(plainText);
                bool success = Utilities.AddSMSUser(phoneNumber, fullname, language, facilityCode,
                    email, title, iActionUserId);
                string output = DataTransformation.Encrypt(success.ToString());
                return output;
            }
            else
            {
                return AUTHENTICATION_FAILED;
            }
        }

        [Obsolete("This method is here for backward compatibility, use UpdateSMSUser2 instead")]
        [WebMethod]
        public string UpdatedSMSUser(int userId, string phoneNumber, string fullname, int language, string facilityCode, string email, string actionUserId)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;
            //bool authenticated = Utilities.AuthenticateUser(actionUserId);
            //if (authenticated)
            //{
            //    string plainText = DataTransformation.Decrypt(actionUserId);
            //    int iActionUserId = Int32.Parse(plainText);
            //    bool success = Utilities.UpdateSMSUser(userId, phoneNumber, fullname, language, facilityCode, email, iActionUserId);
            //    string output = DataTransformation.Encrypt(success.ToString());
            //    return output;
            //}
            //else
            //{
            //    return AUTHENTICATION_FAILED;
            //}
        }

        [WebMethod]
        public string UpdatedSMSUser2(int userId, string phoneNumber, string fullname, int language, string facilityCode, 
            string email, int title, string actionUserId)
        {
            bool authenticated = Utilities.AuthenticateUser(actionUserId);
            if (authenticated)
            {
                string plainText = DataTransformation.Decrypt(actionUserId);
                int iActionUserId = Int32.Parse(plainText);
                bool success = Utilities.UpdateSMSUser(userId, phoneNumber, fullname, language, facilityCode, 
                    email, title, iActionUserId);
                string output = DataTransformation.Encrypt(success.ToString());
                return output;
            }
            else
            {
                return AUTHENTICATION_FAILED;
            }
        }

        [WebMethod]
        public string GetSMSUser(int userId)
        {
            DataTable dataTable = Utilities.GetSMSUser(userId);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetSMSUserByPhoneNumber(string phoneNumber)
        {
            DataTable dataTable = Utilities.GetSMSUser(phoneNumber);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [Obsolete("This method is here for backward compatibility, use CreateNewUser2 instead")]
        [WebMethod]
        public string CreateNewUser(string firstname, string lastname, string username,
            string password, string email, int accessLevelID, string accessLevelValue)
        {
            Exception ex = new Exception(OPERATION_IS_DEPRECATED);
            throw ex;
            //int insertID = Utilities.CreateNewUser(firstname, lastname, username, password,
            //    email, accessLevelID, accessLevelValue);
            //string output = DataTransformation.Encrypt(insertID.ToString());
            //return output;
        }

        [WebMethod]
        public string CreateNewUser2(string firstname, string lastname, string username,
            string password, string email, string phoneNumber, int accessLevelID, string accessLevelValue, 
            int supportingPartnerId, string userSignature)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            if (authenticated)
            {
                string plainText = DataTransformation.Decrypt(userSignature);
                int iActionUserId = Int32.Parse(plainText);
                int insertID = Utilities.CreateNewUser(firstname, lastname, username, password,
                    email, phoneNumber, accessLevelID, accessLevelValue, supportingPartnerId, iActionUserId);
                string output = DataTransformation.Encrypt(insertID.ToString());
                return output;
            }
            else
            {
                return AUTHENTICATION_FAILED;
            }
        }

        [WebMethod]
        public string DeleteUser(int id)
        {
            bool success = Utilities.DeleteUser(id);
            string output = DataTransformation.Encrypt(success.ToString());
            return output;
        }

        [WebMethod]
        public string IsUsernameAvailable(string username)
        {
            bool available = Utilities.IsUsernameAvailable(username);
            string output = DataTransformation.Encrypt(available.ToString());
            return output;
        }
        #endregion

        #region Other Methods
        [WebMethod]
        public string GetSetting(string name)
        {
            string output = Utilities.GetSetting(name);
            output = DataTransformation.Encrypt(output);
            return output;
        }

        [WebMethod]
        public void SetSetting(string name, string value)
        {
            Utilities.SetSetting(name, value);
        }

        [WebMethod]
        public string GetMessageHistory(string phoneNumber)
        {
            DataTable dataTable = Utilities.GetMessageHistory(phoneNumber);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetErrorMessageCount(string phoneNumber)
        {
            int count = Utilities.GetErrorMessageCount(phoneNumber);
            string output = DataTransformation.Encrypt(count.ToString());
            return output;
        }

        [WebMethod]
        public string GetSupportingPartner()
        {
            DataTable dataTable = Utilities.GetSupportingPartner();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region Offline Data
        [WebMethod]
        public string GetOfflineDataFileAfterCutOffPoint(DateTime cutOffPoint)
        {
            HttpContext context = HttpContext.Current;
            HttpRequest request = context.Request;
            Uri uri = request.Url;
            string app = context.Request.ApplicationPath;

            string downloadPath = String.Empty;

            string path = request.PhysicalPath;
            int length = path.LastIndexOf(@"\") + 1;
            string rootPath = path.Substring(0, length);
            string cacheFolder = String.Format(@"{0}\Cache", rootPath);
            string schemaLocation = string.Format(@"{0}\App_Data\DatabaseSchema.sql", rootPath);

            string[] files = Directory.GetFiles(cacheFolder, "*.gz");
            // This line will force recreation of cache anytime it is required, no more caching
            foreach (string file in files) File.Delete(file);
            
            //if (files.Length == 1)
            //{
            //    FileInfo fileInfo = new FileInfo(files[0]);
            //    TimeSpan timespan = DateTime.Now - fileInfo.CreationTime;
            //    if (timespan.Days > AppConfiguration.OfflineDataCacheLifetime) File.Delete(fileInfo.FullName);
            //    else
            //    {
            //        string urlFormat = (app == "/") ?
            //            "{0}://{1}:{2}{3}Cache/{4}" : "{0}://{1}:{2}{3}/Cache/{4}";
            //        downloadPath = String.Format(urlFormat,
            //            uri.Scheme, uri.Host, uri.Port, app, fileInfo.Name);
            //        downloadPath = HttpUtility.UrlPathEncode(downloadPath);
            //        return downloadPath;
            //    }
            //}
            //else
            //{
            //    // This indicates corrupted cache file, just delete them all and create a fresh copy
            //    foreach (string file in files) File.Delete(file);
            //}

            string cacheDB = String.Format(@"{0}App_Data\Cache.mdb", rootPath);
            Utilities.SetSetting(Utilities.SETTING_TEMPLATE_CACHEDB_NAME, cacheDB);
            if (Properties.Settings.Default.SyncFileGeneration)
            {
                Utilities.GetOfflineDBPath2(cutOffPoint, schemaLocation);
                files = Directory.GetFiles(cacheFolder, "*.gz");
                if (files.Length == 1)
                {
                    FileInfo fileInfo = new FileInfo(files[0]);
                    TimeSpan timespan = DateTime.Now - fileInfo.CreationTime;
                    if (timespan.Days > AppConfiguration.OfflineDataCacheLifetime) File.Delete(fileInfo.FullName);
                    else
                    {

                        string urlFormat = (app == "/") ?
                            "{0}://{1}:{2}{3}Cache/{4}" : "{0}://{1}:{2}{3}/Cache/{4}";
                        downloadPath = String.Format(urlFormat,
                            uri.Scheme, uri.Host, uri.Port, app, fileInfo.Name);
                        downloadPath = HttpUtility.UrlPathEncode(downloadPath);
                        return downloadPath;
                    }
                }
                else
                {
                    Exception ex = new Exception("Failed to create offline data");
                    Utilities.LogError(ex, null);
                    throw ex;
                }
                //return GetOfflineDataFile();
                return "Failed to create offline data";
            }
            else
            {
                IQService service = new IQService();
                Thread thread = new Thread(delegate()
                {
                    Utilities.GetOfflineDBPath2(cutOffPoint, schemaLocation);
                });
                thread.Start();
                return Utilities.CACHEDB_STATUS_CREATING;
            }
        }

        [WebMethod]
        [Obsolete("This is here for backward compatibility, use GetOfflineDataFileAfterCutOffPoint")]
        public string GetOfflineDataFile()
        {
            int monthsBack = Properties.Settings.Default.DefaultCutOffMonthsBack;
            DateTime defaultCutOffPoint = DateTime.Now.AddMonths(-monthsBack);
            
            return GetOfflineDataFileAfterCutOffPoint(defaultCutOffPoint);
        }

        //[WebMethod]
        //public string GetDatabaseSchema()
        //{
        //    var schemaCreator = new OfflineDatabaseCreator(AppConfiguration.DBConnectionString, "IQSMS_TestDB.Development");
        //    var schema = schemaCreator.GenerateScripts();
        //    return schema;
        //}
        #endregion

        #region Automatic SMS Reminder
        [WebMethod]
        public string GetCalendarYears()
        {
            DataTable dataTable = Utilities.GetCalendarYears();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetHolidays(int calendarYear)
        {
            DataTable dataTable = Utilities.GetHolidays(calendarYear);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string SaveHolidays(int calendarYear, List<string> dates, List<string> names)
        {
            bool saved = Utilities.SaveHolidays(calendarYear, dates, names);
            string output = DataTransformation.Encrypt(saved.ToString());
            return output;
        }

        [WebMethod]
        public string SaveAutoReminderFacilities(List<string> selectedFacilities)
        {
            bool saved = Utilities.SaveAutoReminderFacilities(selectedFacilities);
            string output = DataTransformation.Encrypt(saved.ToString());
            return output;
        }

        [WebMethod]
        public string SaveAutoReminderDistricts(List<int> selectedDistricts)
        {
            bool saved = Utilities.SaveAutoReminderDistricts(selectedDistricts);
            string output = DataTransformation.Encrypt(saved.ToString());
            return output;
        }

        [WebMethod]
        public string SaveAutoReminderRegions(List<int> selectedRegions)
        {
            bool saved = Utilities.SaveAutoReminderRegions(selectedRegions);
            string output = DataTransformation.Encrypt(saved.ToString());
            return output;
        }

        /// <summary>
        /// Returns the list of facility codes of the facilities which are configured for automatic SMS reminder.
        /// The list is fetched based on the setting in the SysSettings
        /// </summary>
        /// <returns>DataTable object containing the facility codes</returns>
        [WebMethod]
        public string GetAutoReminderFacilities()
        {
            DataTable dataTable = Utilities.GetAutoReminderFacilities();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAutoReminderConfiguredFacilities()
        {
            DataTable dataTable = Utilities.GetAutoReminderConfiguredFacilities();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAutoReminderConfiguredRegions()
        {
            DataTable dataTable = Utilities.GetAutoReminderConfiguredRegions();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAutoReminderConfiguredDistricts()
        {
            DataTable dataTable = Utilities.GetAutoReminderConfiguredDistricts();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string GetAutoReminderReportMessageTemplates()
        {
            DataTable dataTable = Utilities.GetAutoReminderReportMessageTemplates();
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }

        [WebMethod]
        public string SaveAutoReminderReportMessageTemplates(List<bool> enabled, 
            List<int> reportIds, List<string> messageTemplates)
        {
            bool saved = Utilities.SaveAutoReminderReportMessageTemplates(enabled, reportIds, messageTemplates);
            string output = DataTransformation.Encrypt(saved.ToString());
            return output;
        }
        #endregion

        #region MTUHA Reports
        [WebMethod]
        public ReportingError SaveMTUHAReport(string reportingText, string username, string password, string comments)
        {
            return Utilities.SaveMTUHAReport(reportingText, username, password, comments);
        }

        [WebMethod]
        public ReportingError SaveAndUploadToDHISMTUHAReport(string reportingText, string username, string password, 
            string comments, string authorizationText)
        {
            return Utilities.SaveMTUHAReport(reportingText, username, password, comments, true, authorizationText);
        }

        [WebMethod]
        public DataModels.Models.ANCForm GetMTUHAReport(string facilityCode, 
            int reportYear, int reportMonth, bool lessThan20)
        {
            using (var db = new DataModels.Models.Context.IQSMS_TestDBContext())
            {
                db.Configuration.LazyLoadingEnabled = false;
                db.Configuration.ProxyCreationEnabled = false;
                var report = (from r in db.ANCForms
                                  .Include("ANCForm_HudhurioLaKwanza")
                                  .Include("ANCForm_VidokezoVyaHatari")
                                  .Include("ANCForm_PMTCT")
                                  .Include("ANCForm_Malaria")
                              where r.Year == reportYear &&
                              r.Month == reportMonth &&
                              r.FacilityCode == facilityCode &&
                              r.LessThan20 == lessThan20
                              select r).FirstOrDefault();

                if (report != null)
                {
                    // Removing circular reference
                    if (report.ANCForm_HudhurioLaKwanza != null) report.ANCForm_HudhurioLaKwanza.ANCForms = null;
                    if (report.ANCForm_VidokezoVyaHatari != null) report.ANCForm_VidokezoVyaHatari.ANCForms = null;
                    if (report.ANCForm_PMTCT != null) report.ANCForm_PMTCT.ANCForms = null;
                    if (report.ANCForm_Malaria != null) report.ANCForm_Malaria.ANCForms = null;
                }
                return report;
            }
        }

        [WebMethod]
        public DataModels.Models.LDForm GetLDMTUHAReport(string facilityCode,
            int reportYear, int reportMonth, bool lessThan20)
        {
            using (var db = new DataModels.Models.Context.IQSMS_TestDBContext())
            {
                db.Configuration.LazyLoadingEnabled = false;
                db.Configuration.ProxyCreationEnabled = false;
                var report = (from r in db.LDForms
                                  .Include("LDForm_TaarifaYaWaliojifungua")
                                  .Include("LDForm_NjiaYaKujifungua")
                                  .Include("LDForm_MatatizoKablaYaKujifungua")
                                  .Include("LDForm_MatatizoBaadaYaKujifungua")
                                  .Include("LDForm_EmOC")
                                  .Include("LDForm_PMTCT")
                                  .Include("LDForm_WatotoWaliozaliwaMmoja")
                                  .Include("LDForm_WatotoWaliozaliwaMapacha")
                                  .Include("LDForm_WatotoWaliosaidiwaKupumua")
                              where r.Year == reportYear &&
                              r.Month == reportMonth &&
                              r.FacilityCode == facilityCode &&
                              r.LessThan20 == lessThan20
                              select r).FirstOrDefault();

                if (report != null)
                {
                    // Removing circular reference
                    if (report.LDForm_TaarifaYaWaliojifungua != null) report.LDForm_TaarifaYaWaliojifungua.LDForms = null;
                    if (report.LDForm_NjiaYaKujifungua != null) report.LDForm_NjiaYaKujifungua.LDForms = null;
                    if (report.LDForm_MatatizoKablaYaKujifungua != null) report.LDForm_MatatizoKablaYaKujifungua.LDForms = null;
                    if (report.LDForm_MatatizoBaadaYaKujifungua != null) report.LDForm_MatatizoBaadaYaKujifungua.LDForms = null;
                    if (report.LDForm_EmOC != null) report.LDForm_EmOC.LDForms = null;
                    if (report.LDForm_PMTCT != null) report.LDForm_PMTCT.LDForms = null;
                    if (report.LDForm_WatotoWaliozaliwaMmoja != null) report.LDForm_WatotoWaliozaliwaMmoja.LDForms = null;
                    if (report.LDForm_WatotoWaliozaliwaMapacha != null) report.LDForm_WatotoWaliozaliwaMapacha.LDForms = null;
                    if (report.LDForm_WatotoWaliosaidiwaKupumua != null) report.LDForm_WatotoWaliosaidiwaKupumua.LDForms = null;
                }
                return report;
            }
        }

        [WebMethod]
        public DataModels.Models.Facility GetFullFacilityDetails(string facilityCode)
        {
            using (var db = new DataModels.Models.Context.IQSMS_TestDBContext())
            {
                db.Configuration.LazyLoadingEnabled = false;
                db.Configuration.ProxyCreationEnabled = false;
                var facility = (from f in db.Facilities
                                  .Include("District")
                                  .Include("District.Region")
                                where f.FacCode == facilityCode
                                select f).FirstOrDefault();

                if (facility != null)
                {
                    // Removing circular reference
                    if (facility.District != null)
                    {
                        facility.District.Facilities = null;
                        facility.District.Region = null;
                    }
                    //if (facility.Region != null)
                    //{
                    //    facility.Region.Facilities = null;
                    //    facility.Region.Districts = null;
                    //}
                }
                return facility;
            }
        }

        [WebMethod]
        public List<DataModels.Models.Region> GetDetailedAllRegions(int supportingPartnerId, string userSignature)
        {
            bool authenticated = Utilities.AuthenticateUser(userSignature);
            int userId = -1;
            if (authenticated)
            {
                string id = DataTransformation.Decrypt(userSignature);
                userId = Int32.Parse(id);
            }
            else
            {
                throw new Exception("You are not authenticated to perform this operation");
            }            

            using (var db = new DataModels.Models.Context.IQSMS_TestDBContext())
            {
                db.Configuration.LazyLoadingEnabled = false;
                db.Configuration.ProxyCreationEnabled = false;
                var results = from r in db.Regions
                                  .Include("Districts")
                                  .Include("Districts.Facilities")
                               select r;

                var regions = results.ToList();                
                var userInfo = (from u in db.Users
                                    .Include("AccessLevel")
                                where u.ID == userId
                                select u).Single();

                if (userInfo.AccessLevel.AccessName == DataModels.Models.AccessLevel.ADMINISTRATOR_LEVEL)
                {

                }

                if (userInfo.AccessLevel.AccessName == DataModels.Models.AccessLevel.NATION_LEVEL)
                {
                    // Removing restricted facilities based on supporting partner
                    var regionsToRemove = new List<DataModels.Models.Region>();
                    foreach (var r in regions)
                    {
                        var districtsToRemove = new List<DataModels.Models.District>();
                        foreach (var d in r.Districts)
                        {
                            var facilityToRemove = new List<DataModels.Models.Facility>();
                            foreach (var f in d.Facilities)
                            {
                                if (f.SupportingPartnerId != supportingPartnerId) facilityToRemove.Add(f);
                            }
                            
                            foreach (var f in facilityToRemove) d.Facilities.Remove(f);
                            if (d.Facilities.Count == 0) districtsToRemove.Add(d);
                        }

                        foreach (var d in districtsToRemove) r.Districts.Remove(d);
                        if (r.Districts.Count == 0) regionsToRemove.Add(r);
                    }

                    foreach (var r in regionsToRemove) regions.Remove(r);
                }

                if (userInfo.AccessLevel.AccessName == DataModels.Models.AccessLevel.REGION_LEVEL)
                {
                    // Removing restricted regions
                    int regionId = int.Parse(userInfo.AccessLevelValue);
                    var rr = from r in db.Regions
                             where r.RegionNo != regionId
                             select r;
                    foreach (var r in rr) regions.Remove(r);
                }

                if (userInfo.AccessLevel.AccessName == DataModels.Models.AccessLevel.DISTRICT_LEVEL)
                {
                    int districtId = int.Parse(userInfo.AccessLevelValue);
                    int regionId = (from d in db.Districts
                                    where d.DistrictNo == districtId
                                    select d.RegionNo).Single();

                    // Removing restricted regions
                    var rr = from r in db.Regions
                             where r.RegionNo != regionId
                             select r;
                    foreach (var r in rr) regions.Remove(r);

                    // Removing restricted districts
                    var dd = from d in db.Districts
                             where d.DistrictNo != districtId
                             select d;
                    foreach (var r in regions)
                    {
                        foreach (var d in dd) r.Districts.Remove(d);
                    }
                }

                if (userInfo.AccessLevel.AccessName == DataModels.Models.AccessLevel.FACILITY_LEVEL)
                {
                    string facilityCode = userInfo.AccessLevelValue;
                    int districtId = (from f in db.Facilities
                                      where f.FacCode == facilityCode
                                      select f.DistrictId).Single();

                    int regionId = (from d in db.Districts
                                    where d.DistrictNo == districtId
                                    select d.RegionNo).Single();
                    
                    // Removing restricted regions
                    var rr = from r in db.Regions
                             where r.RegionNo != regionId
                             select r;
                    foreach (var r in rr) regions.Remove(r);

                    // Removing restricted districts
                    var dd = from d in db.Districts
                             where d.DistrictNo != districtId
                             select d;
                    foreach (var r in regions)
                    {
                        foreach (var d in dd) r.Districts.Remove(d);
                    }

                    // Removing restricted facilities
                    var ff = from f in db.Facilities
                             where f.FacCode != facilityCode
                             select f;
                    foreach (var r in regions)
                    {
                        foreach (var d in r.Districts)
                        {                            
                            foreach (var f in ff) d.Facilities.Remove(f);
                        }
                    }
                }
               
                // Removing circular reference
                foreach (var region in regions)
                {
                    foreach (var district in region.Districts)
                    {
                        district.Region = null;
                        foreach (var facility in district.Facilities) facility.District = null;
                    }
                    //foreach (var facility in region.Facilities)
                    //{
                    //    facility.District = null;
                    //    //facility.Region = null;
                    //}
                    //region.Facilities = null;
                }
                //return regions.ToList();

                // Sorting the elements in alphabetical order
                regions.Sort();
                foreach (var r in regions)
                {
                    r.Districts.Sort();
                    foreach (var d in r.Districts) d.Facilities.Sort();
                }

                return regions;
            }
        }
        #endregion

        #region Other Systems
        [WebMethod]
        public List<DataModels.Models.ExcelTemplateReport> GetExcelTemplateReports()
        {
            var result = Utilities.GetExcelTemplateReports();
            return result;
        }

        [WebMethod]
        public List<DataModels.Models.ExcelTemplateCellAssociation> GetExcelTemplateSheetCellAssociation(int sheetId)
        {
            var result = Utilities.GetExcelTemplateSheetCellAssociations(sheetId);
            return result;
        }

        [WebMethod]
        public string GetTestingAndCounselingReport(string[] quarters)
        {
            DataTable dataTable = Utilities.GetTestingAndCounselingReport(quarters);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        [WebMethod]
        public bool SaveOptionBPlusServices(DataModels.Models.OptionBPlusFacility facilityInfo)
        {
            bool status = Utilities.SaveOptionBPlusServices(facilityInfo);
            return status;
        }

        [WebMethod]
        public DataModels.Models.OptionBPlusFacility GetOptionBPlusFacilityInfo(string facilityCode)
        {
            var f = Utilities.GetOptionBPlusFacilityInfo(facilityCode);
            return f;
        }

        [WebMethod]
        public bool SaveReportMergingDefinition(string name, string description, int destinationReportId,
            List<int> sourceReportIds, List<string> indicatorDefinitions)
        {
            return Utilities.SaveReportMergingDefinition(name, description, destinationReportId, 
                sourceReportIds, indicatorDefinitions);
        }

        [WebMethod]
        public DataModels.Models.ReportMerge GetReportMergeDetails(int reportMergeId)
        {
            return Utilities.GetReportMergeDetails(reportMergeId);
        }

        [WebMethod]
        public string GetReportingInfo(AccessLevel requestLevel, string requestLevelValue, int reportId,
            int startYear, int startPeriod, int endYear, int endPeriod, AccessLevel userAccessLevel,
            int supportingPartnerId, bool basicInfo)
        {
            DataSet dataSet = Utilities.GetReportingInfo(requestLevel, requestLevelValue, 
                reportId, startYear, startPeriod, endYear, endPeriod, userAccessLevel, 
                supportingPartnerId, basicInfo);

            string output = DataTransformation.Serialize(dataSet, true);
            return output;
        }

        #region Custom Reports - Querying
        [SoapHeader("Authentication")]
        [WebMethod]
        public List<DataModels.Models.QueryCategory> GetAllQueryCategories()
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            var categories = GenericTools.CustomReporting.ReportQuerying.GetAllQueryCategories();
            // Removing circular reference.
            foreach (var category in categories)
            {
                category.CreatedByUser = null;
                category.UpdatedByUser = null;
                
                foreach (var query in category.Queries)
                {
                    query.QueryType = null;
                    query.CreatedByUser = null;
                    query.UpdatedByUser = null;
                    query.DeletedByUser = null;
                    query.QueryType = null;
                    query.QueryCategories = null;
                }
            }

            return categories;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public List<DataModels.Models.Query> GetAllQueries()
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            var queries = GenericTools.CustomReporting.ReportQuerying.GetAllQueries();
            // Removing circular reference.
            foreach (var query in queries)
            {
                query.CreatedByUser = null;
                query.UpdatedByUser = null;
                query.DeletedByUser = null;
                query.QueryType = null;
            }

            return queries;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public int AddQueryCategory(DataModels.Models.QueryCategory queryCategory)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            int status = GenericTools.CustomReporting.ReportQuerying.AddQueryCategory(queryCategory); 
            return status;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public int UpdateQueryCategory(DataModels.Models.QueryCategory queryCategory)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            int status = GenericTools.CustomReporting.ReportQuerying.UpdateQueryCategory(queryCategory);
            return status;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public int DeleteQueryCategory(int queryCategoryId)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            int status = GenericTools.CustomReporting.ReportQuerying.DeleteQueryCategory(queryCategoryId);
            return status;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public int AddQuery(DataModels.Models.Query query, List<DataModels.Models.QueryParameter> parameters)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            int status = GenericTools.CustomReporting.ReportQuerying.AddQuery(query, parameters);
            return status;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public int UpdateQuery(DataModels.Models.Query query, List<DataModels.Models.QueryParameter> parameters)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            int status = GenericTools.CustomReporting.ReportQuerying.UpdateQuery(query, parameters);
            return status;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public int DeleteQuery(DataModels.Models.Query query)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            int status = GenericTools.CustomReporting.ReportQuerying.DeleteQuery(query);
            return status;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public DataModels.Models.User GetUserProfile(int userId)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            var user = GenericTools.CustomReporting.ReportQuerying.GetUserProfile(userId);
            // Removing circular reference.
            user.CreatedByUser = null;
            user.UpdatedByUser = null;
            user.DeletedByUser = null;
            user.SupportingPartner = null;
            user.QueryCategories = null;
            user.Queries = null;
            user.AccessLevel = null;
            user.webpages_Roles = null;

            return user;
        }

        [WebMethod]
        public List<DataModels.Models.QueryType> GetQueryTypes()
        {
            List<DataModels.Models.QueryType> types = ReportQuerying.GetQueryTypes();
            return types;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public int AddQueryIntoCategories(int queryId, List<int> queryCategoryIds, bool keepExistingCategories)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            int status = GenericTools.CustomReporting.ReportQuerying.AddQueryIntoCategories(queryId, queryCategoryIds, keepExistingCategories);
            return status;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public string RunQuery(DataModels.Models.Query query, List<string> parameterValues)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            // Preparing for querying
            ReportQuerying.CommandTimeout = Properties.Settings.Default.RemoteCommandTimeout;
            ReportQuerying.QueryingConnectionString = Properties.Settings.Default.IQSMS_TestDBContext;

            DataTable dataTable = ReportQuerying.RunQuery(query, parameterValues);
            string output = DataTransformation.Serialize(dataTable);
            return output;
        }
        #endregion

        #region Offline Data - From Data Capture
        [SoapHeader("Authentication")]
        [WebMethod]
        public ReportingMessage UploadOfflineReport(DataModels.Models.OfflineData.OfflineReport report, bool overwriteExistingData)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            ReportingMessage reportingMessage = Utilities.SendReport(report.CreatedByUserName, report.ReportMessage, false, report.ReportComments);
            if (overwriteExistingData && (reportingMessage.Status == ReportingError.REPORT_ALREADY_SUBMITTED_LABEL))
            {
                report.ReportMessage = report.ReportMessage + ",RESUBMIT";
                reportingMessage = Utilities.SendReport(report.CreatedByUserName, report.ReportMessage, false, report.ReportComments);
            }

            if (reportingMessage.Status == ReportingError.NO_ERROR_LABEL)
            {
                using (var db = new DataModels.Models.Context.IQSMS_TestDBContext())
                {
                    // Now we are going to keep the record about this transaction.
                    db.OfflineReports.Add(report);
                    db.SaveChanges();
                }
            }

            return reportingMessage;
        }
        #endregion

        #region NEW - Model Data Retrieve
        [SoapHeader("Authentication")]
        [WebMethod]
        public List<DataModels.Models.Report> GetAllExpectedReportsWithDataElements()
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            var output = GenericTools.Models.ModelDataRetriever.GetAllExpectedReports();
            // Here we will try to remove circular references, our main focus wil be
            // on the data elements; The rest we are not interested in web-response
            foreach (var report in output)
            {
                report.AutoReminderReportMessageTemplate = null;
                report.ExpectedReports = null;
                report.ReceivedSMS = null;
                report.ReportBusinessRules = null;
                report.ReportDatas = null;
                report.SMSReminderTrackers = null;
                foreach (var i in report.ReportDataLocations) i.Report = null;
            }
            return output;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public DataModels.Models.Report GetExpectedReportWithDataElements(int reportId)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            var output = GenericTools.Models.ModelDataRetriever.GetExpectedReport(reportId);
            return output;
        }
        #endregion

        #region DHIS Dataset Link
        [SoapHeader("Authentication")]
        [WebMethod]
        public DataModels.Models.DHIS.ReportDataSetLink GetReportDataSetLink(int reportId)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            var output = Utilities.GetReportDataSetLink(reportId);
            // Here we will try to remove circular references, our main focus wil be
            // on the data elements; The rest we are not interested in web-response
            if (output != null)
            {
                output.Report = null;
                foreach (var e in output.ReportDataSetElementsLinks)
                {
                    e.ReportDataSetLink = null;
                    e.ReportIndicator.Report = null;
                }
            }

            return output;
        }

        [SoapHeader("Authentication")]
        [WebMethod]
        public bool SaveReportDataSetLink(DataModels.Models.DHIS.ReportDataSetLink reportDataSetLink)
        {
            if (Authentication == null) throw new Exception("Please provide enough information to authenticate yourself");
            var userProfile = Authentication.GetUserProfile();
            if (userProfile == null) throw new Exception("Please provide valid information to authenticate yourself");

            var output = Utilities.SaveReportDataSetLink(reportDataSetLink);
            return output;
        }
        #endregion
    }
}